import os
from datetime import datetime

from fastapi import APIRouter, UploadFile, Depends, Form, HTTPException
from langchain_community.document_loaders import Docx2txtLoader
from starlette.responses import StreamingResponse, FileResponse
import json


from agent.file_agent import generate_stream_response
from agent.ppt_agent import create_ppt
from models.json_response import JsonData
from service.file_service import FileService

router = APIRouter(
    prefix="/api/file",
    tags=["教学助手"]
)

@router.post("/outline")
async def outline(file: UploadFile,
                file_service: FileService = Depends(FileService)):
    try:
        # 使用FileService来处理文件
        data = file_service.load_file(file)
        return StreamingResponse(
            generate_stream_response(file_service, data),
            media_type="text/event-stream"
        )
    except Exception as e:
        return JsonData.error(f"文件分析失败：{str(e)}")

@router.post("/exam")
async def exam(file: UploadFile,
               knowledge_point: str = Form(...),
               file_service: FileService = Depends(FileService)):
    try:
        content = file.file.read()
        file_location = os.path.join("./file", file.filename)
        with open(file_location, "wb") as f:
            f.write(content)
        
        # 读取文件内容
        if file.filename.endswith('.txt'):
            text = content.decode('utf-8')
        else:
            loader = Docx2txtLoader(file_location)
            data = loader.load()
            text = "".join([doc.page_content for doc in data])
        
        # 直接使用LLM生成题目
        from core.llm import get_default_llm
        llm = get_default_llm()
        
        # 尝试解析模板信息
        import json
        template_data = {}
        try:
            template_data = json.loads(text)
            print(f"解析到模板数据: {template_data}")
        except json.JSONDecodeError:
            print("不是JSON格式，使用简单模式")
        
        # 构建详细的提示词
        if template_data and 'templateName' in template_data:
            # 使用详细模板信息
            prompt = f"""
            请根据以下详细的模板信息生成完整的试卷：

            模板名称：{template_data.get('templateName', '未知模板')}
            试卷名称：{template_data.get('paperName', '测试试卷')}
            模板描述：{template_data.get('description', '')}
            AI辅助描述：{template_data.get('aiDescription', '')}
            
            试卷配置：
            - 总分：{template_data.get('totalScore', 100)}分
            - 时长：{template_data.get('duration', 120)}分钟
            - 难度：{template_data.get('difficulty', '中等')}
            - 学科：{template_data.get('subject', '计算机科学')}
            - 知识点：{', '.join(template_data.get('tags', []))}
            
            题目类型分布：
            - 选择题：{template_data.get('questionTypes', {}).get('choice', 0)}题，每题{template_data.get('scoringRules', {}).get('choice', 4)}分
            - 编程题：{template_data.get('questionTypes', {}).get('programming', 0)}题，每题{template_data.get('scoringRules', {}).get('programming', 15)}分
            - 分析题：{template_data.get('questionTypes', {}).get('analysis', 0)}题，每题{template_data.get('scoringRules', {}).get('analysis', 10)}分
            - 填空题：{template_data.get('questionTypes', {}).get('fill', 0)}题，每题{template_data.get('scoringRules', {}).get('fill', 3)}分
            - 简答题：{template_data.get('questionTypes', {}).get('essay', 0)}题，每题{template_data.get('scoringRules', {}).get('essay', 8)}分
            
            题目要求：
            - 选择题要求：{template_data.get('questionRequirements', {}).get('choice', '基础知识点考察')}
            - 编程题要求：{template_data.get('questionRequirements', {}).get('programming', '编程能力考察')}
            - 分析题要求：{template_data.get('questionRequirements', {}).get('analysis', '分析能力考察')}
            - 填空题要求：{template_data.get('questionRequirements', {}).get('fill', '基础知识点掌握')}
            - 简答题要求：{template_data.get('questionRequirements', {}).get('essay', '综合理解能力')}
            
            额外要求：{template_data.get('additionalDescription', '')}

            请严格按照以上配置生成试卷，要求：
            1. 题目数量必须完全匹配配置
            2. 每题分值必须符合scoringRules设置
            3. 题目内容要符合各类型的要求
            4. 难度要符合模板设置的难度等级
            5. 内容要围绕学科和知识点展开
            
            输出格式为JSON，包含以下结构：
            {{
              "name": "试卷名称",
              "totalScore": 总分,
              "duration": 时长,
              "questions": [
                {{
                  "id": "q1",
                  "type": "choice",
                  "content": "题目内容",
                  "answer": "A",
                  "score": 分值,
                  "options": ["选项A", "选项B", "选项C", "选项D"],
                  "analysis": "解析",
                  "difficulty": "难度",
                  "knowledge": ["知识点"],
                  "tags": ["标签"],
                  "canRegenerate": true
                }}
              ]
            }}

            请直接返回JSON格式，不要包含其他文字。
            """
        else:
            # 使用简单模式
            prompt = f"""
            请根据以下内容生成完整的试卷：

        内容：{text}
        知识点：{knowledge_point}

        要求：
            1. 生成一个完整的试卷，包含多个题目
            2. 题目类型包括选择题、填空题、简答题
            3. 难度适中，适合大学生
            4. 输出格式为JSON，包含以下结构：
               {{
                 "name": "试卷名称",
                 "totalScore": 100,
                 "duration": 120,
                 "questions": [
                   {{
                     "id": "q1",
                     "type": "choice",
                     "content": "题目内容",
                     "answer": "A",
                     "score": 4,
                     "options": ["选项A", "选项B", "选项C", "选项D"],
                     "analysis": "解析",
                     "difficulty": "中等",
                     "knowledge": ["知识点1", "知识点2"],
                     "tags": ["标签1", "标签2"],
                     "canRegenerate": true
                   }}
                 ]
               }}

            请直接返回JSON格式，不要包含其他文字。
            """
        
        try:
            print(f"开始生成试卷，知识点: {knowledge_point}")
            print(f"提示词长度: {len(prompt)}")
            
            response = await llm.ainvoke(prompt)
            questions_json = response.content
            print(f"AI生成完成，响应长度: {len(questions_json)}")
            print(f"响应内容预览: {questions_json[:200]}...")
            
            return StreamingResponse(
                iter([f"data: {questions_json}\n\n"]),
                media_type="text/event-stream"
            )
        except Exception as e:
            print(f"AI生成失败: {str(e)}")
            error_msg = f"生成题目失败：{str(e)}"
            return StreamingResponse(
                iter([f"data: {error_msg}\n\n"]),
                media_type="text/event-stream"
            )
    except Exception as e:
        return {"error": str(e)}


@router.post("/generate-questions")
async def generate_questions(file: UploadFile,
                            knowledge_point: str = Form(...),
                            file_service: FileService = Depends(FileService)):
    """
    专用接口：AI生成考试题目（独立于智能组卷功能）
    """
    try:
        content = file.file.read()
        file_location = os.path.join("./file", file.filename)
        with open(file_location, "wb") as f:
            f.write(content)
        
        # 读取文件内容
        if file.filename.endswith('.txt'):
            text = content.decode('utf-8')
        else:
            loader = Docx2txtLoader(file_location)
            data = loader.load()
            text = "".join([doc.page_content for doc in data])
        
        # 直接使用LLM生成题目
        from core.llm import get_default_llm
        llm = get_default_llm()
        
        # 构建题目生成提示词
        prompt = f"""
        请根据以下要求生成考试题目：

        题目要求：{text}
        知识点：{knowledge_point}

        请生成高质量的考试题目，要求：
        1. 题目内容要准确、清晰、有针对性
        2. 难度要适中，适合大学生水平
        3. 题目类型要多样化
        4. 每个题目都要有详细的解析
        5. 选择题要提供4个选项，且选项要合理

        输出格式为JSON数组，每个题目包含以下字段：
        [
          {{
            "id": "q1",
            "type": "choice",
            "topic": "题目内容",
            "answer": "正确答案",
            "parse": "题目解析",
            "options": ["选项A", "选项B", "选项C", "选项D"],
            "score": 5,
            "difficulty": "easy/medium/hard",
            "knowledgePoint": "相关知识点"
          }},
          {{
            "id": "q2", 
            "type": "programming",
            "topic": "编程题目内容",
            "answer": "参考答案",
            "parse": "题目解析",
            "score": 15,
            "difficulty": "medium",
            "knowledgePoint": "相关知识点"
          }}
        ]

        题目类型说明：
        - choice: 选择题，必须包含options字段
        - programming: 编程题，注重实践能力
        - analysis: 分析题，注重理解分析
        - fill: 填空题，基础知识点
        - essay: 简答题，综合理解

        难度等级：
        - easy: 简单，基础知识点
        - medium: 中等，需要一定理解
        - hard: 困难，需要深入思考

        请直接返回JSON格式的题目数组，不要包含其他文字。
        """
        
        try:
            print(f"开始生成题目，知识点: {knowledge_point}")
            print(f"题目要求: {text}")
            
            response = await llm.ainvoke(prompt)
            questions_json = response.content
            print(f"AI生成完成，响应长度: {len(questions_json)}")
            print(f"响应内容预览: {questions_json[:200]}...")
        
            return StreamingResponse(
                iter([f"data: {questions_json}\n\n"]),
                media_type="text/event-stream"
            )
        except Exception as e:
            print(f"AI生成题目失败: {str(e)}")
            error_msg = f"生成题目失败：{str(e)}"
            return StreamingResponse(
                iter([f"data: {error_msg}\n\n"]),
                media_type="text/event-stream"
            )
    except Exception as e:
        return {"error": str(e)}

@router.post("/generate-pdf")
async def generate_pdf(exam_data: str = Form(...), pdf_type: str = Form("exam")):
    """生成试卷或答案PDF"""
    try:
        # 解析试卷数据
        exam_json = json.loads(exam_data)
        
        # 导入PDF服务
        from service.pdf_service import PDFService
        pdf_service = PDFService()
        
        # 生成PDF
        if pdf_type == "answer":
            pdf_path = pdf_service.generate_answer_pdf(exam_json)
            filename = f"answer_{exam_json.get('name', '试卷')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
        else:
            pdf_path = pdf_service.generate_exam_pdf(exam_json)
            filename = f"exam_{exam_json.get('name', '试卷')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
        
        # 返回PDF文件
        return FileResponse(
            path=pdf_path,
            filename=filename,
            media_type="application/pdf"
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"PDF生成失败：{str(e)}")

@router.post("/ppt")
def ppt(file: UploadFile,
        pages: int = Form(...),
        file_service: FileService = Depends(FileService)):
    try:
        data = file_service.load_file(file)
        chunks = ""
        for chunk in data:
            chunks = chunks + chunk.page_content
        path = create_ppt(chunks, pages)
        return FileResponse(
            path=path,
            filename="ppt.pptx",
            media_type="application/octet-stream"
        )
    except Exception as e:
        return JsonData.error(f"PPT生成失败：{str(e)}")

